﻿using System;
using System.Drawing;

namespace NKnobMan.Templatizer
{
    /// <summary>
    /// Code taken from : http://www.dev102.com/2009/07/23/changing-brush-brightness-in-wpfsilverlight/
    /// </summary>
    public class HSBColor
    {
        public double H { get; set; }

        public double S { get; set; }

        public double B { get; set; }

        public byte A { get; set; }


        public static HSBColor FromColor(Color rgbColor)
        {
            HSBColor result = new HSBColor();

            // preserve alpha
            result.A = rgbColor.A;

            // convert R, G, B to numbers from 0 to 1
            double r = rgbColor.R/255d;
            double g = rgbColor.G/255d;
            double b = rgbColor.B/255d;
            double max = Math.Max(r, Math.Max(g, b));
            double min = Math.Min(r, Math.Min(g, b));

            // hue
            if (max == min)
                result.H = 0;
            else if (max == r)
                result.H = (60*(g - b)/(max - min) + 360)%360;

            else if (max == g)
                result.H = 60*(b - r)/(max - min) + 120;
            else
                result.H = 60*(r - g)/(max - min) + 240;

            // saturation
            if (max == 0)
                result.S = 0;
            else
                result.S = 1 - min/max;

            // brightness
            result.B = max;
            return result;
        }


        public Color ToColor()
        {            
            int resultR = 0;
            int resultG = 0;
            int resultB = 0;
            int resultA = this.A;

            int hi = (int) Math.Floor(this.H/60)%6;

            double f = this.H/60 - Math.Floor(this.H/60);
            double p = this.B*(1 - this.S);
            double q = this.B*(1 - f*this.S);
            double t = this.B*(1 - (1 - f)*this.S);

            switch (hi)
            {
                case 0:
                    resultR = (byte) (B*255);
                    resultG = (byte) (t*255);
                    resultB = (byte) (p*255);
                    break;
                case 1:
                    resultR = (byte) (q*255);
                    resultG = (byte) (B*255);
                    resultB = (byte) (p*255);
                    break;

                case 2:
                    resultR = (byte) (p*255);
                    resultG = (byte) (B*255);
                    resultB = (byte) (t*255);

                    break;

                case 3:

                    resultR = (byte) (p*255);
                    resultG = (byte) (q*255);
                    resultB = (byte) (this.B*255);

                    break;

                case 4:

                    resultR = (byte) (t*255);
                    resultG = (byte) (p*255);
                    resultB = (byte) (this.B*255);

                    break;

                case 5:

                    resultR = (byte) (this.B*255);
                    resultG = (byte) (p*255);
                    resultB = (byte) (q*255);
                    break;

            }
            return Color.FromArgb(resultA, resultR, resultG, resultB);
        }
    }
}